package com.whpost.service.service.stamp;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.whpost.service.config.Wdpz;
import com.whpost.service.dao.stamp.StampHdDhmMapper;
import com.whpost.service.dao.stamp.StampHdDhmMxMapper;
import com.whpost.service.dao.stamp.StampHdMapper;
import com.whpost.service.dao.stamp.StampXmMapper;
import com.whpost.service.dao.t.TDelDao;
import com.whpost.service.entity.stamp.*;
import com.whpost.service.entity.t.TCzy;
import com.whpost.service.entity.t.TDel;
import com.whpost.service.entity.tools.ListInfo;
import com.whpost.service.entity.tools.PageInfo;
import com.whpost.service.entity.tools.ResultInfo;
import com.whpost.service.excel.stamp.MxEntity;
import com.whpost.service.service.BaseServices;
import com.whpost.service.service.t.FileService;
import com.whpost.service.service.t.TApiNonceService;
import com.whpost.service.tools.QRCodeGenerator;
import com.whpost.service.tools.ToolBean;
import com.whpost.service.tools.Url;
import jakarta.annotation.Resource;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

@Service
public class StampHdDhmServices extends BaseServices {

    @Resource
    private StampHdDhmMapper stampHdDhmMapper;
    @Resource
    private StampHdDhmMxMapper stampHdDhmMxMapper;
    @Resource
    private StampXmMapper stampXmMapper;
    @Resource
    private StampHdMapper stampHdMapper;
    @Resource
    private TApiNonceService tApiNonceService;
    @Resource
    private Wdpz wdpz;
    @Resource
    private TDelDao tDelDao;

    @Override
    public ResultInfo info(String loginId, Map<String, Object> map) {
        JSONObject jsonObject = getData(map,loginId);
        if (StringUtils.isEmpty(loginId)){
            return new ResultInfo(500,"用户信息丢失！",null);
        }else{
            TCzy tCzy = new TCzy();
            tCzy = gettCzyDao().selectById(loginId);

            Map<String,Object> infoMap = new HashMap<>();

            String id="";
            if (jsonObject.containsKey("id")) {
                id = jsonObject.getString("id");
            }
            String lx="";
            if (jsonObject.containsKey("lx")) {
                lx = jsonObject.getString("lx");
            }

            if ("1".equals(lx)){
                StampHdDhm stampHdDhm = new StampHdDhm();
                if(StringUtils.isEmpty(id)){
                    return new ResultInfo(500,"修改信息丢失！",null);
                }
                try {
                    id = Url.decrypt(id);
                } catch (Exception e) {
                    throw new RuntimeException("修改信息丢失！");
                }
                stampHdDhm = stampHdDhmMapper.selectById(id);
                if (null!=stampHdDhm){
                    stampHdDhm.setUrlId(ToolBean.getEncode(stampHdDhm.getId()));
                    stampHdDhm.setId(null);
                }
                infoMap.put("stampHdDhm",stampHdDhm);
            }

            //项目筛选，暂时规定，只能选择自己机构的项目
            List<StampHd> stampHdList = stampHdMapper.getList(new QueryWrapper<StampHd>().eq("t_xzjg_id",tCzy.getXzjgId()).eq("state","1"));
            // 循环遍历 List 并改变每个对象的 age 属性
            for (StampHd stampHd : stampHdList) {
                stampHd.setUrlId(ToolBean.getEncode(stampHd.getId()));
                stampHd.setId(null);
            }
            infoMap.put("stampHdList",stampHdList);

            ResultInfo resultInfo = new ResultInfo(0, "成功返回！",infoMap);
            return backRtn(resultInfo,loginId);
        }
    }

    @Override
    public ResultInfo query(String loginId, Map<String, Object> map) {
        JSONObject jsonObject = getData(map,loginId);
        if (StringUtils.isEmpty(loginId)){
            return new ResultInfo(500,"用户信息丢失！",null);
        }else{
            TCzy tCzy = gettCzyDao().selectById(loginId);
            String curpage = "",pagesize="";
            QueryWrapper<StampHdDhm> queryWrapper = new QueryWrapper<>();
            if (jsonObject.containsKey("curpage")) {
                curpage = jsonObject.getString("curpage");
            }
            if (jsonObject.containsKey("pagesize")) {
                pagesize = jsonObject.getString("pagesize");
            }

            if (StringUtils.isEmpty(curpage)) curpage = "1";
            if (StringUtils.isEmpty(pagesize)) pagesize = "10";

            Page<StampHdDhm> page = new Page<>( Integer.parseInt(curpage),  Integer.parseInt(pagesize));

            ListInfo<StampHdDhm> stampHdDhmListInfo = new ListInfo<>();

            queryWrapper.eq("t_xzjg_id",tCzy.getXzjgId());

            queryWrapper.orderByDesc("id");

            IPage<StampHdDhm> stampHdDhmPage = stampHdDhmMapper.getStampHdDhmLPage(page,queryWrapper);

            PageInfo pageInfo = new PageInfo();
            pageInfo.setTotal(stampHdDhmPage.getTotal());
            pageInfo.setCurPage(stampHdDhmPage.getCurrent());
            pageInfo.setPageSize(stampHdDhmPage.getSize());
            pageInfo.setPageTotal(stampHdDhmPage.getPages());

            stampHdDhmListInfo.setPageInfo(pageInfo);

            List<StampHdDhm> stampHdDhmList = stampHdDhmPage.getRecords();

            // 循环遍历 List 并改变每个对象的 age 属性
            for (StampHdDhm stampHdDhm : stampHdDhmList) {
                stampHdDhm.setUrlId(ToolBean.getEncode(stampHdDhm.getId()));
                stampHdDhm.setId(null);
            }

            stampHdDhmListInfo.setListInfo(stampHdDhmList);
            stampHdDhmListInfo.setUserId(loginId);

            List<StampHd> stampHdList = stampHdMapper.getList(new QueryWrapper<StampHd>().eq("t_xzjg_id",tCzy.getXzjgId()).eq("state","1"));

            //查询条件的值
            Map<String,Object> cxtjMap = new HashMap<>();
            cxtjMap.put("stampHdList",stampHdList);
            //cxtjMap.put("cxmc",cxmc);

            //返回前端的内容
            Map<String,Object> rtnMap = new HashMap<>();
            rtnMap.put("cxjg",stampHdDhmListInfo);
            rtnMap.put("cxtj",cxtjMap);

            ResultInfo resultInfo = new ResultInfo(0, "成功返回！",rtnMap);
            return backRtn(resultInfo,loginId);
        }
    }

    @Transactional
    @Override
    public ResultInfo save(String loginId, Map<String, Object> map) {
        JSONObject jsonObject = getData(map,loginId);
        if (StringUtils.isEmpty(loginId)){
            return new ResultInfo(500,"用户信息丢失！",null);
        }else{
            String lx="",id="",nonce_ms="",nonce_zhi="",hd_id="",scsl="";
            if (jsonObject.containsKey("nonce_ms")) {
                nonce_ms = jsonObject.getString("nonce_ms");
            }
            if (jsonObject.containsKey("nonce_zhi")) {
                nonce_zhi = jsonObject.getString("nonce_zhi");
            }
            if (jsonObject.containsKey("hd_id")) {
                hd_id = jsonObject.getString("hd_id");
            }
            if (jsonObject.containsKey("scsl")) {
                scsl = jsonObject.getString("scsl");
            }
            if (StringUtils.isEmpty(scsl)) scsl="1000";

            //参数校验
            if (StringUtils.isEmpty(hd_id)){
                return new ResultInfo(500,"关键参数丢失！",null);
            }

            try {
                hd_id = Url.decrypt(java.net.URLDecoder.decode(hd_id,"utf-8"));
            } catch (Exception e) {
                e.printStackTrace();
                throw new RuntimeException("活动信息获取失败！");
            }

            //校验nonce
            ResultInfo ResultInfoCheckNonce = new ResultInfo();
            ResultInfoCheckNonce = tApiNonceService.checkNonce(nonce_ms,loginId,nonce_zhi,"增加兑换码！");

            if (ResultInfoCheckNonce.getCode()!=200)
            {
                return ResultInfoCheckNonce;
            }

            TCzy tCzy = gettCzyDao().getCzyById(loginId);

            StampHd stampHd = null;
            try {
                ToolBean.info("准备解密："+hd_id);
                stampHd = stampHdMapper.selectById(hd_id);
            } catch (Exception e) {
                e.printStackTrace();
                throw new RuntimeException("活动信息获取失败！");
            }

            ResultInfo resultInfo;
            if (null==stampHd){
                resultInfo = new ResultInfo(500, "活动不存在！",null);
                return backRtn(resultInfo,loginId);
            }

            if (!stampHd.getTCzyId().equals(tCzy.getId())){
                resultInfo = new ResultInfo(500, "非自己创建的活动，无法生成兑换码！",null);
                return backRtn(resultInfo,loginId);
            }

            StampHdDhm stampHdDhm = new StampHdDhm();
            stampHdDhm.setXmId(stampHd.getXmId());
            stampHdDhm.setHdId(stampHd.getId());
            stampHdDhm.setScsl(Long.parseLong(scsl));
            stampHdDhm.setTCzyId(tCzy.getId());
            stampHdDhm.setAddRq(ToolBean.getToday());
            stampHdDhm.setTXzjgId(tCzy.getXzjgId());
            stampHdDhmMapper.insert(stampHdDhm);

            StampHdDhmMx stampHdDhmMx = new StampHdDhmMx();

            //开始生成明细
            for (int i=0;i<Integer.parseInt(scsl);i++){
                String dhm="";
                // 获取原始字符串
                String zjm = stampHd.getZjm();
                // 处理参数：为空则用"DHM"，长度超3则取前3位，否则用原字符串
                String param = (zjm == null || zjm.isEmpty()) ? "DHM" :
                        (zjm.length() > 3 ? zjm.substring(0, 3) : zjm);
                // 生成最终结果
                dhm = generateSingleCode(param);

                //看是否存在
                try {
                    if (stampHdDhmMxMapper.selectCount(new QueryWrapper<StampHdDhmMx>().eq("dhm",Url.encrypt(dhm)))>0){
                        dhm = dhm+ToolBean.getRandomString(3);
                    }
                    stampHdDhmMx = new StampHdDhmMx();
                    stampHdDhmMx.setZbId(stampHdDhm.getId());
                    stampHdDhmMx.setXmId(stampHd.getXmId());
                    stampHdDhmMx.setHdId(stampHd.getId());
                    stampHdDhmMx.setDhm(Url.encrypt(dhm));
                    stampHdDhmMxMapper.insert(stampHdDhmMx);

                } catch (Exception e) {
                    throw new RuntimeException("兑换码生成错误！");
                }
            }
            resultInfo = new ResultInfo(1, "新增成功！",null);
            return backRtn(resultInfo,loginId);
        }
    }

    /**
     * 生成单个兑换码
     * @param prefix 兑换码前缀（如"DM"）
     * @return 12位兑换码（前缀+10位字符，含3-4位大写字母，其余为数字）
     */
    public static String generateSingleCode(String prefix) {
        Random random = new Random();
        String numbers = "0123456789"; // 数字字符集
        String letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; // 大写字母字符集

        // 生成10位随机数字
        StringBuilder numPart = new StringBuilder();
        for (int i = 0; i < 10; i++) {
            numPart.append(numbers.charAt(random.nextInt(numbers.length())));
        }

        // 随机决定替换3位还是4位数字为字母
        int replaceCount = random.nextBoolean() ? 3 : 4;

        // 随机选择不重复的替换位置（0-9之间）
        Set<Integer> positions = new HashSet<>();
        while (positions.size() < replaceCount) {
            positions.add(random.nextInt(10));
        }

        // 替换指定位置为随机字母
        char[] codeChars = numPart.toString().toCharArray();
        for (int pos : positions) {
            codeChars[pos] = letters.charAt(random.nextInt(letters.length()));
        }

        // 拼接前缀返回完整兑换码
        return prefix + new String(codeChars);
    }
}
